package com.example.mmlist2;

import static android.content.ContentValues.TAG;
import static android.content.Context.MODE_PRIVATE;

import androidx.biometric.BiometricManager;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;

import com.example.mmlist2.databinding.FragmentFirstBinding;
import com.example.mmlist2.mode.NavigationViewModel;
import com.example.mmlist2.storage.EncryptionUtils;

import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.concurrent.Executor;

import javax.crypto.SecretKey;

public class FirstFragment extends Fragment {

    private FragmentFirstBinding binding;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentFirstBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // 如果不是从ListFragment返回，则进行指纹认证
        NavigationViewModel navigationViewModel = new ViewModelProvider(requireActivity()).get(NavigationViewModel.class);
        if (!navigationViewModel.getIsReturningFromListFragment()) {
            checkBiometricAndAuthenticate();
        } else {
            navigationViewModel.setReturningFromListFragment(false); // 重置标志位
        }
        binding.fpAuthPage.setOnClickListener(view1 -> checkBiometricAndAuthenticate());
    }

    /**
     * 检查设备上是否支持生物识别，并使用生物识别进行身份验证。
     */
    private void checkBiometricAndAuthenticate() {
        BiometricManager biometricManager = BiometricManager.from(Objects.requireNonNull(getContext()));
        int authenticationResult = biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG);
        switch (authenticationResult) {
            case BiometricManager.BIOMETRIC_SUCCESS:
                login();
                break;
            case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
                notifyUser("由于硬件不可用，无法进行身份验证。稍后再试.");
                break;
            case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
                notifyUser("无法进行身份验证，因为没有合适的硬件");
                break;
            case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
                notifyUser("无法进行身份验证，因为没有注册生物特征或设备凭据");
                break;
            default:
                // 处理未知或未来的状态
                notifyUser("生物特征认证失败，原因未知");
                break;
        }
    }

    /**
     * 登录方法，使用指纹登录
     */
    public void login() {
        BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
                .setTitle("指纹登录")
                .setDescription("请将手指放于指纹传感器上")
                .setNegativeButtonText("取消")
                .build();
        getPrompt().authenticate(promptInfo);
    }

    private BiometricPrompt getPrompt() {
        Executor executor = ContextCompat.getMainExecutor(Objects.requireNonNull(getContext()));
        BiometricPrompt.AuthenticationCallback callback = new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
                Log.d(TAG, "onAuthenticationError: " + errorCode);
                if (errorCode == BiometricPrompt.ERROR_LOCKOUT) {
                    notifyUser("认证次数过多，请等待30s后再进行尝试");
                }
                if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
                    notifyUser("认证取消");
                }
            }

            @Override
            public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                notifyUser("指纹认证成功");
                // 保存密码密钥
                SharedPreferences sharedPreferences = Objects.requireNonNull(getActivity()).getSharedPreferences("MyPreferences", MODE_PRIVATE);
                String encodedToken = sharedPreferences.getString("pass", null);
                if (encodedToken == null) {
                    SecretKey secretKey;
                    try {
                        secretKey = EncryptionUtils.generateSecretKey();
                    } catch (NoSuchAlgorithmException e) {
                        throw new RuntimeException(e);
                    }
                    byte[] token = secretKey.getEncoded();
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    editor.putString("pass", Base64.encodeToString(token, Base64.DEFAULT));
                    editor.apply();
                }

                NavHostFragment.findNavController(FirstFragment.this)
                        .navigate(R.id.action_FirstFragment_to_ListFragment);
            }

            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                notifyUser("指纹认证失败");
            }
        };
        return new BiometricPrompt(this, executor, callback);
    }

    private void notifyUser(String message) {
        Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

}